package cn.ch.system.service.impl;

/*
@Service
public class PermissionScanServiceImpl implements IPermissionScanService {

    private static final String  PKG_PREFIX   = "cn.ch.";
    private static final String  PKG_SUFFIX   = ".controller";

    @Autowired
    private PermissionMapper permissionMapper;//注入permissionmapper
    @Override
    public void annoScan() {
        //1.获取cn.ch下面所有的模块目录
        String path = this.getClass().getResource("/").getPath() + "/cn/ch/";
        File file = new File(path);
        File[] files = file.listFiles(new FileFilter() {
            @Override
            public boolean accept(File file) {
                return file.isDirectory();
            }
        });
        //获取cn.ch.*.controller里面所有的类
        Set<Class> clazzes = new HashSet<>();
        for (File fileTmp : files) {
            System.out.println(fileTmp.getName());
            clazzes.addAll(Classutil.getClasses(PKG_PREFIX+fileTmp.getName()+PKG_SUFFIX));
        }
        for (Class clazz : clazzes) {
            Method[] methods = clazz.getMethods();
            //2.遍历Controller方法
            for (Method method : methods) {
                String uri = getUri(clazz, method);
                try {
                    //3.判断是否打上了注解
                    PreAuthorize preAuthorizeAnno = method.getAnnotation(PreAuthorize.class);
                    //4.如果没有就不要管
                    if (preAuthorizeAnno==null) {
                        continue;
                    }
                    //5.如果有就保存
                    String name = preAuthorizeAnno.name();
                    String permissionSn = preAuthorizeAnno.value();
                    Permission permissionTmp = permissionMapper.loadBySn(permissionSn);
                    //如果不存在就添加
                    if (permissionTmp == null) {
                        Permission permission = new Permission();
                        permission.setName(name);
                        permission.setSn(permissionSn);
                        permission.setUrl(uri);
                        permissionMapper.save(permission);
                    }else{
                        //如果不存在就修改
                        permissionTmp.setName(name);
                        permissionTmp.setSn(permissionSn);
                        permissionTmp.setUrl(uri);
                        permissionMapper.update(permissionTmp);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //2.创建getURI，根据不同请求获取 uri
    private String getUri(Class clazz, Method method) {
        String classPath = "";
        Annotation annotation = clazz.getAnnotation(RequestMapping.class);
        if (annotation!=null){
            RequestMapping requestMapping = (RequestMapping) annotation;
            String[] values = requestMapping.value();
            if(values!=null&&values.length>0){
                classPath = values[0];
                if (!"".equals(classPath)&&!classPath.startsWith("/"))
                    classPath="/"+classPath;
            }
        }
        GetMapping getMapping =  method.getAnnotation(GetMapping.class);
        String methodPath = "";
        if (getMapping!=null){
            String[] values = getMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        PostMapping postMapping =  method.getAnnotation(PostMapping.class);
        if (postMapping!=null){
            String[] values = postMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        DeleteMapping deleteMapping =  method.getAnnotation(DeleteMapping.class);
        if (deleteMapping!=null){
            String[] values = deleteMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        PutMapping putMapping =  method.getAnnotation(PutMapping.class);
        if (putMapping!=null){
            String[] values = putMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }

        }
        PatchMapping patchMapping = method.getAnnotation(PatchMapping.class);
        if (patchMapping!=null){
            String[] values = patchMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
        if (requestMapping!=null){
            String[] values = requestMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        return classPath+methodPath;
    }

    private String getPermissionSn(String value) {
        String regex = "\\[(.*?)]";
        Pattern p = Pattern.compile("(?<=\\()[^\\)]+");
        Matcher m = p.matcher(value);
        String permissionSn =null;
        if (m.find()){
            permissionSn= m.group(0).substring(1, m.group().length()-1);
        }
        return permissionSn;
    }


}
*/


import cn.ch.basic.util.Classutil;
import cn.ch.system.anno.PreAuthorize;
import cn.ch.system.domain.Permission;
import cn.ch.system.mapper.PermissionMapper;
import cn.ch.system.service.IPermissionScanService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.FileFilter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 自定义注解扫描
 * 获取注解内容，保存数据到permission
 */
@Service
public class PermissionScanServiceImpl implements IPermissionScanService {
    @Autowired
    private PermissionMapper permissionMapper;


    private static final String  PKG_PREFIX   = "cn.ch.";
    private static final String  PKG_SUFFIX   = ".controller";

    @Override
    public void annoScan() {
        //获取target/classes/cn/ch下面所有的模块目录
        String path = this.getClass().getResource("/").getPath() + "/cn/ch/";
        File file = new File(path);
        File[] files = file.listFiles(new FileFilter() {
            @Override
            public boolean accept(File file) {
                return file.isDirectory();
            }
        });

        //获取cn.ch.*.controller里面所有的类
        Set<Class> clazzes = new HashSet<>();
        for (File fileTmp : files) {
            System.out.println(fileTmp.getName());
            // cn.ch.org.controller
            clazzes.addAll(Classutil.getClasses(PKG_PREFIX+fileTmp.getName()+PKG_SUFFIX));
        }
        //1.遍历clazzes，读取所有controller
        for (Class clazz : clazzes) {
            //2.遍历controller中的方法
            Method[] methods = clazz.getMethods();
            for (Method method : methods) {
                //3.是否方法上打了注解PreAuthorize
                PreAuthorize anno = method.getAnnotation(PreAuthorize.class);
                //3.2 如果没有注解，那么就不管
                if(anno == null){
                    continue;//跳过
                }
                //3.1 如果有注解，需要拿到注解内容保存permission
                //4.判断曾今是否已经增加过权限，有则改，无则加
                String uri = getUri(clazz, method);//当前方法的请求uri
                String name = anno.name();
                String sn = anno.value();
                Permission permission = permissionMapper.loadBySn(sn);
                if(permission == null){
                    permission = new Permission();
                    permission.setName(name);
                    permission.setSn(sn);
                    permission.setUrl(uri);
                    permissionMapper.save(permission);
                }else{
                    permission.setName(name);
                    permission.setSn(sn);
                    permission.setUrl(uri);
                    permissionMapper.update(permission);
                }
            }
        }
    }

    /**
     * 获取方法请求路径
     * @param clazz 哪一个类
     * @param method 哪一个方法
     * @return
     */
    private String getUri(Class clazz, Method method) {
        String classPath = "";
        Annotation annotation = clazz.getAnnotation(RequestMapping.class);
        if (annotation!=null){
            RequestMapping requestMapping = (RequestMapping) annotation;
            String[] values = requestMapping.value();
            if(values!=null&&values.length>0){
                classPath = values[0];
                if (!"".equals(classPath)&&!classPath.startsWith("/"))
                    classPath="/"+classPath;
            }
        }
        GetMapping getMapping =  method.getAnnotation(GetMapping.class);
        String methodPath = "";
        if (getMapping!=null){
            String[] values = getMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        PostMapping postMapping =  method.getAnnotation(PostMapping.class);
        if (postMapping!=null){
            String[] values = postMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        DeleteMapping deleteMapping =  method.getAnnotation(DeleteMapping.class);
        if (deleteMapping!=null){
            String[] values = deleteMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        PutMapping putMapping =  method.getAnnotation(PutMapping.class);
        if (putMapping!=null){
            String[] values = putMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }

        }
        PatchMapping patchMapping = method.getAnnotation(PatchMapping.class);
        if (patchMapping!=null){
            String[] values = patchMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
        if (requestMapping!=null){
            String[] values = requestMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        return classPath+methodPath;
    }

    private String getPermissionSn(String value) {
        String regex = "\\[(.*?)]";
        Pattern p = Pattern.compile("(?<=\\()[^\\)]+");
        Matcher m = p.matcher(value);
        String permissionSn =null;
        if (m.find()){
            permissionSn= m.group(0).substring(1, m.group().length()-1);
        }
        return permissionSn;
    }
}

